package com.hifar.test.api.log;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hifar.test.api.model.DataRequest;
import com.hifar.test.api.model.DataResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * API日志记录器
 * 用于记录数据资产管理平台接口的请求和响应日志
 */
@Component
public class ApiLogger {
    
    private static final Logger logger = LoggerFactory.getLogger(ApiLogger.class);
    private static final Logger apiLogger = LoggerFactory.getLogger("API_LOGGER");
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 记录请求日志
     * 
     * @param requestId 请求ID
     * @param username 用户名
     * @param request 请求对象
     */
    public void logRequest(String requestId, String username, DataRequest request) {
        try {
            String timestamp = LocalDateTime.now().format(formatter);
            String requestJson = objectMapper.writeValueAsString(request);
            
            apiLogger.info("[{}] [{}] [REQUEST] [{}] {}", 
                    timestamp, requestId, username, requestJson);
        } catch (Exception e) {
            logger.error("记录请求日志失败", e);
        }
    }
    
    /**
     * 记录响应日志
     * 
     * @param requestId 请求ID
     * @param username 用户名
     * @param response 响应对象
     * @param duration 请求耗时（毫秒）
     */
    public void logResponse(String requestId, String username, DataResponse response, long duration) {
        try {
            String timestamp = LocalDateTime.now().format(formatter);
            String responseJson = objectMapper.writeValueAsString(response);
            
            apiLogger.info("[{}] [{}] [RESPONSE] [{}] [{}ms] {}", 
                    timestamp, requestId, username, duration, responseJson);
        } catch (Exception e) {
            logger.error("记录响应日志失败", e);
        }
    }
    
    /**
     * 记录错误日志
     * 
     * @param requestId 请求ID
     * @param username 用户名
     * @param error 错误信息
     * @param exception 异常对象
     */
    public void logError(String requestId, String username, String error, Exception exception) {
        try {
            String timestamp = LocalDateTime.now().format(formatter);
            
            apiLogger.error("[{}] [{}] [ERROR] [{}] {} - {}", 
                    timestamp, requestId, username, error, 
                    exception != null ? exception.getMessage() : "Unknown error");
            
            if (exception != null) {
                apiLogger.error("异常堆栈:", exception);
            }
        } catch (Exception e) {
            logger.error("记录错误日志失败", e);
        }
    }
    
    /**
     * 记录认证日志
     * 
     * @param requestId 请求ID
     * @param username 用户名
     * @param success 是否成功
     */
    public void logAuth(String requestId, String username, boolean success) {
        try {
            String timestamp = LocalDateTime.now().format(formatter);
            String status = success ? "SUCCESS" : "FAILED";
            
            apiLogger.info("[{}] [{}] [AUTH] [{}] 用户认证{}", 
                    timestamp, requestId, username, status);
        } catch (Exception e) {
            logger.error("记录认证日志失败", e);
        }
    }
    
    /**
     * 记录业务日志
     * 
     * @param requestId 请求ID
     * @param username 用户名
     * @param action 操作类型
     * @param message 日志消息
     */
    public void logBusiness(String requestId, String username, String action, String message) {
        try {
            String timestamp = LocalDateTime.now().format(formatter);
            
            apiLogger.info("[{}] [{}] [BUSINESS] [{}] [{}] {}", 
                    timestamp, requestId, username, action, message);
        } catch (Exception e) {
            logger.error("记录业务日志失败", e);
        }
    }
    
    /**
     * 生成请求ID
     * 
     * @return 请求ID
     */
    public String generateRequestId() {
        return "REQ_" + System.currentTimeMillis() + "_" + Thread.currentThread().getId();
    }
}
